﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace NMF.Languages
{
    public class IntegerType : DataType
    {
        public IntegerType()
            : base("Integer")
        {
            mMinimum = int.MinValue;
            mMaximum = int.MaxValue;
        }

        private long mMinimum;

        public long Minimum
        {
            get
            {
                return mMinimum;
            }
            set
            {
                mMinimum = value;
                UpdateType();
            }
        }

        private long mMaximum;

        public long Maximum
        {
            get
            {
                return mMaximum;
            }
            set
            {
                mMaximum = value;
                UpdateType();
            }
        }

        private System.Type systemType;

        private void UpdateType()
        {
            if (Minimum >= 0)
            {
                if (Minimum < byte.MaxValue && Maximum <= byte.MaxValue)
                {
                    systemType = typeof(byte);
                    return;
                }
                if (Minimum < ushort.MaxValue && Maximum <= ushort.MaxValue)
                {
                    systemType = typeof(ushort);
                    return;
                }
                if (Minimum < uint.MaxValue && Maximum <= uint.MaxValue)
                {
                    systemType = typeof(uint);
                    return;
                }
                systemType = typeof(ulong);
            }
            else
            {
                if (Minimum >= sbyte.MinValue && Minimum < sbyte.MaxValue && Maximum <= sbyte.MaxValue)
                {
                    systemType = typeof(sbyte);
                    return;
                }
                if (Minimum >= short.MinValue && Minimum < short.MaxValue && Maximum <= short.MaxValue)
                {
                    systemType = typeof(short);
                    return;
                }
                if (Minimum >= int.MinValue && Minimum < int.MaxValue && Maximum <= int.MaxValue)
                {
                    systemType = typeof(int);
                    return;
                }
                systemType = typeof(long);
            }
        }
        

        public override System.Type SystemType
        {
            get { return systemType; }
        }

        public override void Visit(ITypeVisitor visitor)
        {
            visitor.VisitInteger(this);
        }

        public override T Visit<T>(ITypeVisitor<T> visitor)
        {
            return visitor.VisitInteger(this);
        }

        public override T Visit<S, T>(ITypeVisitor<S, T> visitor, S parameter)
        {
            return visitor.VisitInteger(this, parameter);
        }
    }
}
